#pragma once

#include <QObject>
#include <memory>
#include <functional>
#include <type_traits>

// Forward declarations
namespace infrastructure {
class ServiceContainer;
}

namespace application {
class MapApplicationService;
namespace vehicle {
class VehicleService;
}
namespace task {
class TaskService;
}
namespace simulation {
class SimulationService;
}
}

namespace presentation {
class MapViewModel;
class DashboardViewModel;
namespace viewmodels {
class VehicleViewModel;
class TaskViewModel;
class ResourceViewModel;
class SimulatorViewModel;
class LogViewModel;
}
}

namespace presentation {
namespace factories {

/**
 * @brief ViewModel工厂类
 * @details 负责创建和配置ViewModel实例，实现应用层服务的依赖注入
 * 
 * 设计原则：
 * 1. 类型安全：编译时检查服务依赖关系
 * 2. 统一管理：所有ViewModel通过工厂创建
 * 3. 服务注入：自动解析和注入应用层服务
 * 4. 生命周期：与QML组件生命周期同步
 */
class ViewModelFactory : public QObject {
    Q_OBJECT

public:
    explicit ViewModelFactory(std::shared_ptr<infrastructure::ServiceContainer> serviceContainer, 
                             QObject* parent = nullptr);
    ~ViewModelFactory() = default;

    /**
     * @brief 创建MapViewModel实例
     * @param parent 父对象
     * @return MapViewModel实例
     */
    Q_INVOKABLE QObject* createMapViewModel(QObject* parent = nullptr);

    /**
     * @brief 创建DashboardViewModel实例
     * @param parent 父对象
     * @return DashboardViewModel实例
     */
    Q_INVOKABLE QObject* createDashboardViewModel(QObject* parent = nullptr);

    /**
     * @brief 创建VehicleViewModel实例
     * @param parent 父对象
     * @return VehicleViewModel实例
     */
    Q_INVOKABLE QObject* createVehicleViewModel(QObject* parent = nullptr);

    /**
     * @brief 创建TaskViewModel实例
     * @param parent 父对象
     * @return TaskViewModel实例
     */
    Q_INVOKABLE QObject* createTaskViewModel(QObject* parent = nullptr);

    /**
     * @brief 创建ResourceViewModel实例
     */
    Q_INVOKABLE QObject* createResourceViewModel(QObject* parent = nullptr);

    /**
     * @brief 创建SimulatorViewModel实例
     * @param parent 父对象
     * @return SimulatorViewModel实例
     */
    Q_INVOKABLE QObject* createSimulatorViewModel(QObject* parent = nullptr);

    /**
     * @brief 创建LogViewModel实例
     * @param parent 父对象
     * @return LogViewModel实例
     */
    Q_INVOKABLE QObject* createLogViewModel(QObject* parent = nullptr);

    /**
     * @brief 创建带服务注入的MapViewModel实例
     * @param mapAppService 地图应用服务
     * @param parent 父对象
     * @return MapViewModel实例
     */
    QObject* createMapViewModel(
        application::MapApplicationService* mapAppService,
        QObject* parent = nullptr);

    /**
     * @brief 创建带服务注入的VehicleViewModel实例
     * @param vehicleService 车辆应用服务
     * @param parent 父对象
     * @return VehicleViewModel实例
     */
    QObject* createVehicleViewModel(
        application::vehicle::VehicleService* vehicleService,
        QObject* parent = nullptr);

    /**
     * @brief 创建带服务注入的TaskViewModel实例
     * @param taskService 任务应用服务
     * @param parent 父对象
     * @return TaskViewModel实例
     */
    QObject* createTaskViewModel(
        application::task::TaskService* taskService,
        QObject* parent = nullptr);

    /**
     * @brief 检查服务容器是否可用
     */
    bool isServiceContainerAvailable() const;

    /**
     * @brief 获取服务容器
     */
    std::shared_ptr<infrastructure::ServiceContainer> getServiceContainer() const;

    /**
     * @brief 通用ViewModel创建模板
     * @tparam ViewModelType ViewModel类型
     * @param parent 父对象
     * @return ViewModel实例
     */
    template<typename ViewModelType>
    ViewModelType* createViewModel(QObject* parent = nullptr);

signals:
    /**
     * @brief ViewModel创建成功信号
     */
    void viewModelCreated(const QString& viewModelType);

    /**
     * @brief ViewModel创建失败信号
     */
    void viewModelCreationFailed(const QString& viewModelType, const QString& error);

private:
    std::shared_ptr<infrastructure::ServiceContainer> m_serviceContainer;
    
    /**
     * @brief 记录ViewModel创建日志
     */
    void logViewModelCreation(const QString& type, bool success, const QString& error = QString());
};

} // namespace factories
} // namespace presentation
